package com.tm.fiverole.security.filter;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.tm.fiverole.result.Result;
import com.tm.fiverole.result.ResultEnum;
import com.tm.fiverole.security.domain.User;
import com.tm.fiverole.ulits.JwtTokenUtil;
import com.tm.fiverole.ulits.ResponseUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 11.13新建一个用于验证JWT的过滤器类
 */
public class JwtAuthenticationTokenFilter extends BasicAuthenticationFilter {

    public JwtAuthenticationTokenFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String tokenHeader = request.getHeader("Authorization");
        if (StringUtils.isNotBlank(tokenHeader) && tokenHeader.startsWith("Bearer")) {
            try {
                // 截取JWT前缀
                String token = tokenHeader.replace("Bearer", "");
                // 解析JWT
                Claims claims = JwtTokenUtil.parseToken(token);
                // 获取用户名
                String username = claims.getSubject();
                String userId=claims.getId();
                if(StringUtils.isNotBlank(username) && StringUtils.isNotBlank(userId)) {
                    // 获取角色
                    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    String authoritiesStr = claims.get("authorities").toString();
                    if(StringUtils.isNotBlank(authoritiesStr)){
                       ObjectMapper objectMapper = new ObjectMapper();
                        JsonNode jsonNode = objectMapper.readTree(authoritiesStr);
                        Iterator<JsonNode> elements = jsonNode.elements();
                        while (elements.hasNext()){
                            JsonNode next = elements.next();
                            authorities.add(new SimpleGrantedAuthority(next.path("authority").asText()));
                        }
                    }
                    //组装参数
                    User user = new User();
                    user.setUsername(claims.getSubject());
                    user.setId(Long.parseLong(claims.getId()));
                    user.setAuthorities(authorities);
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(user, userId, authorities);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            } catch (ExpiredJwtException e){
                ResponseUtil.out(response, Result.ERROR(ResultEnum.TOKEN_HASH_EXPIRED));
            } catch (Exception e) {
                ResponseUtil.out(response, Result.ERROR(ResultEnum.TOKEN_IS_INVALID));
            }
        }
        filterChain.doFilter(request, response);
    }
}